'use strict';

const path = require('path')
const fse = require('fs-extra') // 文件相关的操作
const pkgDir = require('pkg-dir').sync
const pathExists = require('path-exists').sync
const npminstall = require('npminstall')        // 实现自动安装依赖
const { isObject } = require('@hjy-cli/utils')
const formatPath = require('@hjy-cli/format-path')
const { getDefaultRegistry, getNpmLatestVersion } = require('@hjy-cli/get-npm-info')

class Package {
    constructor (options) {
        console.log('Package constructor')

        if (!options) {
            throw new Error('Package类的options参数不能为空！')
        }
        if (!isObject(options)) {
            throw new Error('Package类的options参数必须为对象！')
        }
        // Package的目标路径
        this.targetPath = options.targetPath
        // 缓存package的路径
        this.storeDir = options.storeDir
        // package的name
        this.packageName = options.packageName
        // package的version
        this.packageVersion = options.packageVersion
        // package的缓存目录前缀
        this.cacheFilePathPrefix = this.packageName.replace('/', '_')
    }

    // 获取npm上最新版本
    async prepare() {
        // 当目录不存在
        if (this.storeDir && !pathExists(this.storeDir)) {
            // 创建目录
            fse.mkdirpSync(this.storeDir)
        }
        if (this.packageVersion === 'latest') {
            this.packageVersion = await getNpmLatestVersion(this.packageName)
        }
        console.log('this.packageVersion =======>', this.packageVersion)
    }

    // 针对当前的npm
    // _@hjy-cli_init@1.1.2@@hjy-cli/
    get cacheFilePath() {
        return path.resolve(this.storeDir, `_${this.cacheFilePathPrefix}@${this.packageVersion}@${this.packageName}`)
    }

    // 生成一个指定版本
    getSpecificCacheFilePath(packageVersion) {
        return path.resolve(this.storeDir, `_${this.cacheFilePathPrefix}@${packageVersion}@${this.packageName}`)
    }

    // 判断当前的Package是否存在
    async exists() {
        if (this.storeDir) {    // 缓存模式
            await this.prepare()    // 获取npm上最新版本
            console.log('this.cacheFilePath', this.cacheFilePath)
            return pathExists(this.cacheFilePath)
        } else {
            return pathExists(this.targetPath)
        }
    }

    // 安装Package
    async install () {
        await this.prepare()

        return npminstall({
            root: this.targetPath,// 模块的路径
            storeDir: this.storeDir,// 实际存储的位置
            registry: getDefaultRegistry(true),// 指定默认的源（也可以切到淘宝源）
            pkgs: [// 需要安装的插件名称和版本号
                {
                    name: this.packageName,
                    version: this.packageVersion
                }
            ]
        })
    }

    // 更新Package
    async update() {
        await this.prepare()
        // 1、获取最新的npm模块版本号
        const latestPackageVersion = await getNpmLatestVersion(this.packageName)
        // 2、查询最新版本号对应的路径是否存在
        const latestFilePath = this.getSpecificCacheFilePath(latestPackageVersion)
        console.log('latestFilePath', latestFilePath)
        // 3、如果不存在，则直接安装最新版本
        if (!pathExists(latestFilePath)) {
            await npminstall({
                root: this.targetPath,
                storeDir: this.storeDir,
                registry: getDefaultRegistry(),
                pkgs: [{
                    name: this.packageName,
                    version: latestPackageVersion
                }]
            })
            this.packageVersion = latestPackageVersion
        } else {
            this.packageVersion = latestPackageVersion
        }
    }

    // 获取入口文件的路径
    // hjy-cli init --targetPath D:\software\java\workspace\hjy-cli\commands\init\lib --debug test-project --force
    getRootFilePath () {
        function _getRootFile(targetPath) {
            // 1、获取package.json所在目录
            const dir = pkgDir(targetPath)
            if (dir) {
                // 2、读取package.json

                const pkgFile = require(path.resolve(dir, 'package.json'))
                console.log('pkgFile', pkgFile)
                // pkgFile = {
                //     name: '@hjy-cli/init',
                //     version: '1.0.0',
                //     description: 'hjy-cli init',
                //     author: 'junyong.hong <125173449@qq.com>',
                //     homepage: '',
                //     license: 'ISC',
                //     main: 'lib/index.js',
                //     directories: { lib: 'lib', test: '__tests__' },
                //     files: [ 'lib' ],
                //     publishConfig: { access: 'public' },
                //     repository: { type: 'git', url: 'https://gitee.com/hongjunyong/hjy-cli.git' },
                //     scripts: { test: 'echo "Error: run tests from root" && exit 1' },
                //     dependencies: {}
                // }

                // 3、寻找main/lib
                if (pkgFile && pkgFile.main) {
                    // 4、路径的兼容(maxOs/windows)
                    return formatPath(path.resolve(dir, pkgFile.main))
                }
            }
            return null
        }

        if (this.storeDir) {    // 使用缓存
            return _getRootFile(this.cacheFilePath)
        } else {    // 不使用缓存
            return _getRootFile(this.targetPath)
        }
    }
}

module.exports = Package;

